const signale = require('signale');
const boxen = require("boxen");
const os = require("os");
const prettyBytes = require('pretty-bytes');
const si = require('systeminformation');

const title =
    `             系统信息查看工具
                       --by:郝杰

* 获取系统信息约耗时三秒，请勿中途关闭窗口
* 因平台差异，部分信息会显示为空
* 获取的系统信息不保证完全正确，结果仅供参考`;
const box = boxen(title, {
    borderColor: "green",
    borderStyle: "classic",
    padding: 1,
    margin: 1
})
console.log(box);

signale.start("开始获取系统信息……");

systemInfo()
    .then(() => cpuInfo()
        .then(() => memInfo()
            .then(() => graphInfo()
                .then(() => osInfo()
                    .then(() => diskInfo()
                        .then(() => fsInfo()
                            .then(() => networkInfo()
                                .then(() => loadInfo()))))))))

async function systemInfo() {
    signale.star("************系统（硬件）信息************");
    const sysData = await si.system();
    signale.info("生产商：" + sysData.manufacturer);
    signale.info("型号：" + sysData.model);
    const biosData = await si.bios();
    signale.info("BIOS厂商：" + biosData.vendor);
    signale.info("BIOS版本：" + biosData.version);
    signale.info("BIOS发布日期：" + biosData.releaseDate);
    const baseboardData = await si.baseboard();
    signale.info("主板厂商：" + baseboardData.manufacturer);
    signale.info("主板型号：" + baseboardData.model);
    signale.info("主板版本：" + baseboardData.version);
}
async function cpuInfo() {
    signale.star("*****************CPU信息*****************");
    const cpuData = await si.cpu();
    signale.info("厂商：" + cpuData.manufacturer);
    signale.info("品牌：" + cpuData.brand);
    signale.info("频率：" + cpuData.speed + "GHz");
    signale.info("核心(Cores)：" + cpuData.cores);
    signale.info("物理核心：" + cpuData.physicalCores);
    signale.info("处理器：" + cpuData.processors);
    const speedData = await si.cpuCurrentspeed()
    signale.info("CPU最小频率：" + speedData.min);
    signale.info("CPU最大频率：" + speedData.max);
    signale.info("CPU平均频率：" + speedData.avg);
    signale.info("频率概览：" + speedData.cores);
}

async function memInfo() {
    signale.star("*****************内存信息*****************");
    const memData = await si.mem()
    signale.info("总内存：" + prettyBytes(memData.total));
    signale.info("已用内存：" + prettyBytes(memData.used));
    signale.info("空闲内存：" + prettyBytes(memData.free));
    signale.info("虚拟内存：" + prettyBytes(memData.swaptotal));
    signale.info("已用虚拟内存：" + prettyBytes(memData.swapused));
    signale.info("空闲虚拟内存：" + prettyBytes(memData.swapfree));
}

async function graphInfo() {
    signale.star("*****************显卡信息*****************");
    const graphData = await si.graphics()
    graphData.controllers.map(item => {
        signale.info("型号：" + item.model);
        signale.info("生产商：" + item.vendor);
        signale.info("显存：" + item.vram + "MB");
        signale.info("是否动态显存：" + (item.vramDynamic ? "是" : "否"));
    })
}

async function osInfo() {
    signale.star("*****************系统信息*****************");
    const osData = await si.osInfo()
    signale.info("平台：" + osData.arch);
    signale.info("系统：" + osData.distro);
    signale.info("发行版：" + osData.logofile);
    signale.info("版本号：" + osData.release);
    signale.info("内核：" + osData.kernel);
    signale.info("主机名：" + osData.hostname);
    signale.info("用户目录：" + os.homedir())
    signale.info("临时文件目录：" + os.tmpdir())
}

async function diskInfo() {
    signale.star("*****************磁盘信息*****************");
    const diskData = await si.diskLayout()
    diskData.map(item => {
        signale.info("名称：" + item.name);
        signale.info("类型：" + item.type);
        signale.info("挂载位置：" + item.device);
        signale.info("容量：" + prettyBytes(item.size));
        signale.info("固件版本：" + item.firmwareRevision);
        signale.info("接口类型：" + item.interfaceType);
        signale.info("smart状态：" + item.smartStatus);
    })
}

async function fsInfo() {
    signale.star("*****************分区信息*****************");
    const blockData = await si.blockDevices();
    const fsData = await si.fsSize();
    for (let i = 0; i < blockData.length; i++) {
        let blockItem = blockData[i];
        let fsItem = fsData[i];
        signale.info("名称：" + blockItem.name);
        signale.info("类型：" + blockItem.type);
        signale.info("文件系统类型：" + blockItem.fstype);
        signale.info("挂载点：" + blockItem.mount);
        try {
            signale.info("容量：" + prettyBytes(parseInt(blockItem.size)));
            signale.info("已使用容量：" + prettyBytes(fsItem.used));
            signale.info("使用率：" + fsItem.use.toFixed(2) + "%");
        } catch (err) {
            signale.info("容量：");
            signale.info("已使用容量：");
            signale.info("使用率：");
        }
        signale.info("物理类型：" + blockItem.physical);
        signale.info("是否可拆卸：" + (blockItem.removable ? "是" : "否"));
        signale.info("协议：" + blockItem.protocol);
    }
}
async function networkInfo() {
    signale.star("*****************网络信息*****************");
    const networkData = await si.networkInterfaces()
    networkData.map(item => {
        signale.info("网络连接：" + item.iface);
        signale.info("网卡名称：" + item.ifaceName);
        signale.info("IP地址：" + item.ip4);
        signale.info("mac地址：" + item.mac);
        signale.info("连接类型：" + item.type);
    })
    const defaultNetData = await si.networkInterfaceDefault()
    signale.info("默认网络连接：" + defaultNetData)
}

async function loadInfo() {
    signale.star("**************进程和性能信息**************");
    const loadData = await si.currentLoad()
    signale.info("平均负载：" + loadData.avgload.toFixed(2) + "%");
    signale.info("当前负载：" + loadData.currentload.toFixed(2) + "%");
    signale.info("用户负载：" + loadData.currentload_user.toFixed(2) + "%");
    signale.info("系统负载：" + loadData.currentload_system.toFixed(2) + "%");
    let loadCount = 1;
    loadData.cpus.map(item => {
        signale.info("核心" + loadCount + "负载：" + item.load.toFixed(2) + "%");
        signale.info("核心" + loadCount + "用户负载：" + item.load_user.toFixed(2) + "%");
        signale.info("核心" + loadCount + "系统负载：" + item.load_system.toFixed(2) + "%");
        loadCount++;
    })
    const proceData = await si.processes()
    signale.info("进程数量：" + proceData.all);
    signale.info("运行进程数量：" + proceData.running);
    signale.info("阻断进程数量：" + proceData.blocked);
    signale.info("睡眠进程数量：" + proceData.sleeping);
    signale.info("未知进程数量：" + proceData.unknown);
    signale.success("结束获取系统信息！");
}